const mongoose = require('mongoose')
const bcrypt = require('bcrypt-nodejs')
const jwt = require('jsonwebtoken')
const User = mongoose.model('user')
const Group = mongoose.model('group')
const Socket = mongoose.model('socket')
const config = require('../config')
const { formatBody, sleep } = require('../tools')

module.exports = {
  async login (info, socket, cb) {
    let { email, password } = info
    let user = await User.findOne({ email: email })
    if(!user) {
      return cb(formatBody(0, '不存在该用户'))
    }
    if(bcrypt.compareSync( password, user.password)) {
      // 将该在线用户保存进socket集合
      let sock = new Socket({ user: user._id, socket_id: socket.id })
      user.socket = sock._id
      user.onlineState = true
      sock.save()
      user.save()
      // 生成token返回给客户端
      let exp = Math.floor((new Date().getTime())/1000) + 60 * 60 * 24 * 30
      let token = await jwt.sign({ user_id: user._id, exp }, config.server.SIGN_KEY )
      socket.broadcast.emit('online',{ _id: user._id, nickname: user.nickname })
      return cb(formatBody(1, '登陆成功', {
        token,
        user: {
          _id: user._id,
          nickname: user.nickname,
          avatar: user.avatar,
          sex: user.sex,
          place: user.place,
          email: user.email,
          groups: user.groups
        }
      }))
    }
    return cb(formatBody(0, '密码错误'))
  },

  async autoLogin (info, socket, cb) {
    const { _id } = info
    let user = await User.findOne({ _id: _id })
    if(user) {      
      let sock = new Socket({ user: user._id, socket_id: socket.id }) 
      user.socket = sock._id
      user.onlineState = true
      await user.save()
      await sock.save()
      socket.broadcast.emit('online',{_id: user._id, nickname: user.nickname});
      const { _id, nickname, avatar, sex, place, email, matchState, groups } = user
      return cb(formatBody(1, 'ok', { _id, nickname, avatar, sex, place, email, matchState, groups }))
    }
    return cb(formatBody(0, 'autoLogin failed！'))
  },

  // async getCode
  async signUp (info, socket, cb) {
    let { nickname, email, password } = info
    if (!nickname || !email || !password) {
      return cb(formatBody(0, '昵称，邮箱，密码都不可为空'))
    }
    // let repnickname = await User.find({ nickname: nickname })
    let repemail = await User.find({ email: email })
    if(repemail.length) {
      return cb(formatBody(0, '邮箱已经被注册过啦'))
    }
    // password加盐
    password = bcrypt.hashSync(password, bcrypt.genSaltSync(10))
    // 新建该用户实例
    let user = new User ({ nickname, email, password })
    let exp = Math.floor((new Date().getTime())/1000) + 60 * 60 * 24 * 30
    let token = await jwt.sign({ user_id: user._id, exp }, config.server.SIGN_KEY)
    let initGroup = await Group.find({}).limit(1)
    initGroup = initGroup[0]
    // console.log(`initGroup>>>`, initGroup)
    user.groups.push(initGroup._id)
    initGroup.members.push(user._id)
    
    await user.save()
    await initGroup.save()
    return cb(formatBody(1, '注册成功', { token, user }))
  },
  // 随机匹配聊天
  async updateMathState (info, socket, cb, io) {
    // 匹配状态matchState 1-未开始匹配 2-等待匹配 3-匹配成功
    let { uid, matchState } = info

    let user = await User.findOne({
      _id: uid
    }).populate('socket','socket_id')

    await User.update({
      _id: uid
    }, {
      $set: { matchState }
    })

    if (matchState === 1) {
      let nowState = user.matchState
      if (nowState === 3) {
        // 通知当前匹配对象 我已经离开
        let matchUser = await User.findOne({
          _id: user.matchUser
        }).populate('socket','socket_id')

        await User.update({
          _id: user.matchUser
        }, {
          $set: {
            matchState: 1
          }
        })

        io.to(matchUser.socket.socket_id).emit('random chat', {
          id: uid,
          type: 'leave'
        })

      }
      return cb(formatBody(1, 'ok', {}))
    } else if (matchState === 2) {
      // 当前在线且在等待匹配的用户
      let matchUserList = await User.find({
        matchState: 2,
        onlineState: true,
        _id: { $ne: uid }
      })
      let len = matchUserList.length
      if (len > 0) {
        let random = Math.floor(Math.random() * len)
        let randomId = matchUserList[random]._id
        let randomTarget = await User.findOne({
          _id: randomId
        }).populate('socket','socket_id')
        await User.update({
          _id: uid
        }, { 
          $set: {
            matchState: 3,
            matchUser: randomId
          }
        })
        await User.update({
          _id: randomId
        }, { 
          $set: {
            matchState: 3,
            matchUser: uid
          }
        })
        io.to(randomTarget.socket.socket_id).emit('random chat', {
          id: uid,
          type: 'enter'
        })
        return cb(formatBody(1, 'ok', { id: randomId, type: 'enter' }))
      } else {
        return cb(formatBody(0, '暂无在线的匹配对象'))
      }
    } else if (matchState === 3) {
      return cb(formatBody(1, 'ok'))
    }
  },
  async disconnect (info, socket, io) {
    let online = await Socket.findOne({
      socket_id: socket.id
    }).populate({
      path: 'user',
      select: '_id nickname matchState matchUser'
    })
    if (online) {
      await User.update({
        _id: online.user._id
      }, {
        $set: {
          matchState: 1,
          matchUser: null,
          onlineState: false,
          lastOnline: new Date()
        }
      })
      if (online.user.matchState === 3) {
        // 通知当前匹配对象 我已经离开
        let matchUser = await User.findOne({
          _id: online.user.matchUser
        }).populate('socket','socket_id')

        await User.update({
          _id: online.user.matchUser
        }, {
          $set: {
            matchState: 1,
            matchUser: null
          }
        })

        io.to(matchUser.socket.socket_id).emit('random chat', {
          id: online.user._id,
          type: 'leave'
        })
        console.log(99999)
      }
      await Socket.remove({socket_id: socket.id})

      socket.broadcast.emit('offline',{_id: online.user._id, nickname: online.user.nickname})
      console.log(`--------------------${online.user.nickname}下线了`);
    }
  },
  // 获取用户列表
  async getUserList (ctx, cb) {
    let list = await User.find({}, { nickname: 1, email: 1 })
    let total = list.length
    if (ctx) return ctx.body = formatBody(1, 'ok', { total, list })
    cb(list)
  },
  // 获取用户信息
  async getUserInfo (ctx) {
    let { _id } = ctx.query
    if (!_id) return ctx.body = formatBody(0, '没有用户id，0.0！')
    const user = await User.findOne({ _id: _id })
    if(user) {
      const { _id, nickname, avatar, sex, place, onlineState, createAt } = user
      return ctx.body = formatBody(1, 'ok', { _id, nickname, avatar, sex, place, onlineState, createAt })
    }
    return ctx.body = formatBody(0, '不存在此用户')
  },
  // 更新用户信息
  async update (ctx) {
    let { nickname, _id, place, sex, avatar } = ctx.request.body.fields
    // console.log(ctx.request.body.fields)
    let user = await User.findOne({ _id: _id })
    if (Date.now() - new Date(user.lastUpdate).getTime() < 1000 * 60 * 60 * 2) {
      return ctx.body = formatBody(0, '每2小时只能更改一次个人信息')
    } else {
      await User.update({
        _id: _id
      }, {
        nickname, avatar, place, sex,
        lastUpdate: new Date()
      })
      return ctx.body = formatBody(1, 'ok')
    }
  }
}
